package pers.fish.sso.server.mapping;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import pers.fish.sso.common.model.Authentication;
import pers.fish.sso.server.mapping.model.SsoClient;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 写点什么吧
 *
 * @author fish
 * @date 2020/1/30 16:21
 */
@Component
public class TicketDataMappingStorage {

    /**
     * tgt与用户信息对应
     */
    private final Map<String, Authentication> tgt2Authentication = new ConcurrentHashMap<>();

    /**
     * ticket和tgt信息对应
     */
    private final Map<String,String> ticket2Tgt = new ConcurrentHashMap<>();
    /**
     * tgt与客户端对应
     */
    private final Map<String, List<SsoClient>> tgt2Client = new ConcurrentHashMap<>();

    /**
     * 存储用户凭证信息
     * @param ticket
     * @param tgt
     * @param authentication
     */
    public void storageAuthentication(String ticket,String tgt, Authentication authentication) {
        tgt2Authentication.put(tgt, authentication);
        ticket2Tgt.put(ticket,tgt);
        updateClientList(ticket,tgt);
    }

    /**
     * 更新客户端列表
     * @param ticket
     * @param tgt
     */
    public void updateClientList(String ticket, String tgt) {
        List<SsoClient> ssoClients = tgt2Client.get(tgt);
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String serverUrl = wrapServerUrl(request);
        if(CollectionUtils.isEmpty(ssoClients)){
            List<SsoClient> list = new ArrayList<>();

            SsoClient ssoClient = new SsoClient();
            ssoClient.setTicket(ticket);
            ssoClient.setUpdateDate(System.currentTimeMillis());
            ssoClient.setServerUrl(serverUrl);
            list.add(ssoClient);

            tgt2Client.put(tgt,list);
        }else {
            boolean exist = false;
            for (SsoClient ssoClient : ssoClients) {
                if(ssoClient.getServerUrl().equals(serverUrl)){
                    ssoClient.setUpdateDate(System.currentTimeMillis());
                    ssoClient.setTicket(ticket);
                    exist = true;
                }
            }
            if(!exist){
                SsoClient ssoClient = new SsoClient();
                ssoClient.setTicket(ticket);
                ssoClient.setUpdateDate(System.currentTimeMillis());
                ssoClient.setServerUrl(serverUrl);
                ssoClients.add(ssoClient);
            }
        }
    }

    /**
     * 组装服务端url
     * @param request
     * @return
     */
    private String wrapServerUrl(HttpServletRequest request) {
        String service = request.getParameter("service");
        if(StringUtils.isBlank(service)){
            StringBuilder sb = new StringBuilder();
            sb.append(request.getScheme());
            sb.append("://");
            sb.append(request.getServerName());
            sb.append(":");
            sb.append(request.getServerPort());
            sb.append("/");
            sb.append(request.getContextPath());
            return sb.toString();
        }
        if(service.contains("?")){
            service = service.substring(0,service.indexOf("?"));
        }
        return service;
    }

    /**
     * 获取用户凭证信息
     * @param ticket
     * @return
     */
    public Authentication getAuthenticationByTicket(String ticket){
        String tgt = ticket2Tgt.get(ticket);
        if(StringUtils.isBlank(tgt)){
            return null;
        }
        return tgt2Authentication.get(tgt);
    }

    public Authentication getAuthenticationByTgt(String tgt){

        return tgt2Authentication.get(tgt);
    }

}
